package com.dong.web.util;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.dong.web.tool.AForm;
import com.dong.web.tool.HashAForm;
import com.dong.web.tool.MultiFile;
import com.dong.web.tool.MultiForm;
import com.dong.web.tool.MultiForms;
import com.dong.web.whold.Variables;

public final class ActionUtil {

	public static AForm<String, Object> getMap(HttpServletRequest req) {
		return getMap(req, Variables.ENCODING);
	}

	@SuppressWarnings("unchecked")
	private static AForm<String, Object> getMap(HttpServletRequest req,
			String encoding) {
		Map<String, String[]> reqMap = req.getParameterMap();
		AForm<String, Object> rn = new HashAForm<String, Object>();
		Iterator<Entry<String, String[]>> entries = reqMap.entrySet()
				.iterator();
		while (entries.hasNext()) {
			Object value = "";
			Map.Entry<?, ?> entry = entries.next();
			// System.out.println(entry.getKey()
			// + " : "
			// + (entry.getValue().getClass().isArray() ? Arrays
			// .toString((Object[]) (entry.getValue())) : entry
			// .getValue()));
			String key = entry.getKey().toString();
			if (key.startsWith(Variables.START)) {
				key = key.substring(Variables.START.length());
				Object obj = entry.getValue();
				if (obj == null) {
					value = "";
				} else if (obj instanceof String[]) {
					String[] values = (String[]) obj;
					if (values.length <= 1) {
						value = values.length < 1 ? null : getDecode(values[0],
								encoding);
					} else {
						List<Object> list = new ArrayList<Object>();
						for (String text : values) {
							list.add(getDecode(text, encoding));
						}
						value = list;
					}
				} else {
					value = getDecode(obj.toString(), encoding);
				}
				rn.put(key, value);
			} else {
				Object obj = entry.getValue();
				if (obj == null) {
					value = "";
				} else if (obj instanceof String[]) {
					String[] values = (String[]) obj;
					if (values.length <= 1) {
						value = values.length < 1 ? null : values[0];
					} else {
						List<Object> list = new ArrayList<Object>();
						list.addAll(Arrays.asList(values));
						value = list;
					}
				} else {
					value = obj;
				}
				rn.put(key, value);
			}
		}
		if (rn.containsKey(Variables.ASLIST)) {
			String asListText = rn.get(Variables.ASLIST).toString();
			String[] asListArray = asListText.split(",");
			for (String asText : asListArray) {
				if (rn.containsKey(asText)) {
					Object o = rn.get(asText);
					if (o.getClass().equals(String.class)
							|| o instanceof String) {
						String value = o.toString();
						rn.put(asText, Arrays.asList(value.split(",")));
					}
				}
			}
		}
		return rn;
	}

	public static Object getParameter(HttpServletRequest req, String key) {
		return getParameter(req, key, Variables.ENCODING);
	}

	public static Object getParameter(HttpServletRequest req, String key,
			String encoding) {
		return getMap(req, encoding).get(key);
	}

	private static String getDecode(String value, String encoding) {
		try {
			return URLDecoder.decode(value, encoding);
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	public static MultiForms getMultiForms(HttpServletRequest req) {
		String encoding = Variables.ENCODING;
		DiskFileItemFactory factory = new DiskFileItemFactory();
		ServletFileUpload upload = new ServletFileUpload(factory);
		upload.setHeaderEncoding(encoding);
		if (!ServletFileUpload.isMultipartContent(req)) {
			return null;
		}
		MultiForms form = new MultiForms();
		List<MultiFile> multifiles = new ArrayList<MultiFile>();
		AForm<String, Object> aform = new HashAForm<String, Object>();
		try {
			List<FileItem> list = upload.parseRequest(req);
			for (FileItem item : list) {
				if (item.isFormField()) {
					String name = item.getFieldName();
					String value = item.getString(encoding);
					if (aform.containsKey(name)) {
						Object obj = aform.get(name);
						if (obj instanceof List) {
							((List<Object>) obj).add(value);
						} else {
							List<Object> listed = new ArrayList<Object>();
							listed.add(obj);
							listed.add(value);
							aform.remove(name);
							aform.put(name, listed);
						}
					} else {
						aform.put(name, value);
					}
				} else {
					MultiFile multifile = new MultiFile();
					multifile.setField(item.getFieldName());
					String filename = item.getName();
					if (filename == null || filename.trim().equals("")) {
						continue;
					}
					filename = filename.replace("\\", "/").replace("//", "/");
					filename = filename
							.substring(filename.lastIndexOf("/") + 1);
					multifile.setFileName(filename);
					multifile.setInputStream(item.getInputStream());
					multifile.setSize(item.getSize());
					multifiles.add(multifile);
				}
			}
		} catch (FileUploadException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		form.setAform(aform);
		form.setMultifiled(multifiles);
		return form;
	}

	public static MultiForm getMultiForm(HttpServletRequest req) {
		MultiForms multiformed = getMultiForms(req);
		if (multiformed == null) {
			return null;
		}
		MultiForm multiform = new MultiForm();
		if (multiformed.getAform() != null) {
			multiform.setAform(multiformed.getAform());
		}
		if (multiformed.getMultifiled() != null
				&& multiformed.getMultifiled().size() > 0) {
			multiform.setMultifiled(multiformed.getMultifiled().get(0));
		}
		return multiform;
	}

	public static boolean saveFile(MultiFile multifile, String path) {
		FileOutputStream out = null;
		InputStream in = null;
		try {
			in = multifile.getInputStream();
			out = new FileOutputStream(path);
			byte buffer[] = new byte[1024];
			int len = 0;
			while ((len = in.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		} finally {
			try {
				if (out != null) {
					out.close();
				}
				if (in != null) {
					in.close();
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return true;
	}

}
